[Xamarin.Forms] Properties Dictionaryを使ってデータを永続化する
はじめに
こんにちは。モバイルアプリサービス部の加藤 潤です。 今回はXamarin.Formsでデータを永続化する仕組みであるProperties Dictionaryを使ってみました。
検証環境
- Xamarin Studio Community バージョン 6.2(build 1821)
- Xamarin.Forms バージョン 2.3.3.193
実行結果
先に実行結果を載せておきます。 iOSは10.2のシミュレーター、Androidは実機(Androidバージョン6.0.1のNexus 5)で動かしています。
iOS | Android |
簡単にアプリの説明をすると、
アプリを起動するとテキストを入力するコントロールと、Saveボタンが表示されます。
テキストを入力し、Saveボタンをタップすると入力したテキストが永続化されます。
アプリを再起動した時に永続化されたデータを取得し、ラベルに表示しています。
ソースコード
アプリの初期ページであるAppClassFeaturePage
のXAMLは以下のようにしました。
<?xml version="1.0" encoding="utf-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AppClassFeature" x:Class="AppClassFeature.AppClassFeaturePage"> <StackLayout VerticalOptions="Center"> <Entry x:Name="Entry" Placeholder="保存するテキストを入力してください。" HorizontalOptions="Center" Margin="20"></Entry> <Button x:Name="SaveButton" Text="Save" HorizontalOptions="Center" Clicked="Handle_Clicked"></Button> <Label x:Name="Label" Text="" HorizontalOptions="Center"></Label> </StackLayout> </ContentPage>
また、コードビハインドは以下のように実装しました。
public partial class AppClassFeaturePage : ContentPage { private const string PropertyKeyMyText = "myText"; public AppClassFeaturePage() { InitializeComponent(); // 保存されているテキストをラベルに表示 UpdateLabelText(); } void Handle_Clicked(object sender, System.EventArgs e) { // 保存 Application.Current.Properties[PropertyKeyMyText] = this.Entry.Text; // 保存されているテキストをラベルに表示 UpdateLabelText(); } private void UpdateLabelText() { if (Application.Current.Properties.ContainsKey(PropertyKeyMyText)) { this.Label.Text = Application.Current.Properties[PropertyKeyMyText] as string; } } }
データの保存は
Application.Current.Properties[PropertyKeyMyText] = this.Entry.Text;
保存したデータの取得は
Application.Current.Properties[PropertyKeyMyText] as string;
で行なっています。非常に簡単ですね!
データが保存されるタイミング
Application.Current.Properties
にキーと値をセットすればデータは自動的に保存されるのですが、保存タイミングは即時ではないようです。iOSで確認した結果、データはボタンをタップしたタイミングではなく、ホームボタンをタップしてアプリがバックグラウンドに移行したタイミングで保存されていました。
即時保存したい場合はキーと値をセットした後、Application.Current.SavePropertiesAsync();
を呼ぶようにしてください。
データはどこに保存されるのか
データがどこに保存されるのか気になったので調べてみました。
iOS
iOS(シミュレーター)の場合は以下の場所に保存されていました。
/Users/<ユーザー名>/Library/Developer/CoreSimulator/Devices/<デバイスID>/data/Containers/Data/Application/<アプリID>/Documents/.config/.isolated-storage/PropertyStore.forms
以下はファイルをAtomで開いた結果です。ちゃんと指定したキーと値が保存されていることが確認できました。
@ArrayOfKeyValueOfstringanyType9http://schemas.microsoft.com/2003/10/Serialization/Arrays i)http://www.w3.org/2001/XMLSchema-instance@KeyValueOfstringanyType@Key�myText@Value.type�a:string a http://www.w3.org/2001/XMLSchema�This is test data
Android
Androidは以下の場所に保存されていました。
/data/data/<アプリのパッケージ名>/files/.config/.isolated-storage/PropertyStore.forms
ファイルの内容はiOSと同じでした。
@ArrayOfKeyValueOfstringanyType9http://schemas.microsoft.com/2003/10/Serialization/Arrays i)http://www.w3.org/2001/XMLSchema-instance@KeyValueOfstringanyType@Key�myText@Value.type�a:string a http://www.w3.org/2001/XMLSchema�This is test data
Xamarin Studioからは以下の手順でAndroid実機のアプリ内に保存されたファイルにアクセスできました。
- Xamarin Studioの「ツール」からSDK Command Promptを起動
- adb shell
- run-as <アプリのパッケージ名>
- cat files/.config/.isolated-storage/PropertyStore.forms
ちなみに
Xamarinのソースコードは公開されているので、Properties Dictionaryがどのような実装になっているかは以下を覗いてみるといいと思います。筆者も覗いてみて、
「ふむふむ、CoreでDependencyService使ってる!」→「ということは実装は各プラットフォーム毎にありそう」→「あった!」という感じで読むことができました。
- Xamarin.Forms.Core/Application.cs
- Xamarin.Forms.Platform.iOS/Deserializer.cs
- Xamarin.Forms.Platform.Android/Deserializer.cs
おわりに
今回はProperties Dictionaryを使ってiOS、Androidそれぞれでデータを保存してみました。 iOSのUserDefaultsやAndroidのSharedPreferencesとは異なる場所、ファイル名で永続化されることがわかりました。 また、データは暗号化などはされずそのまま保存されるので、パスワードなどは保存しないようにしましょう。